const express = require('express');
const multer = require('multer');
const { exec } = require('child_process');
const fs = require('fs').promises;
const path = require('path');
const cors = require('cors');

const app = express();
const PORT = process.env.PORT || 3000;

// 中间件
app.use(cors());
app.use(express.json());
app.use(express.static('public'));

// 文件上传配置
const storage = multer.diskStorage({
  destination: async (req, file, cb) => {
    const uploadDir = './uploads';
    await fs.mkdir(uploadDir, { recursive: true });
    cb(null, uploadDir);
  },
  filename: (req, file, cb) => {
    const timestamp = Date.now();
    cb(null, `${timestamp}_${file.originalname}`);
  }
});

const upload = multer({ 
  storage,
  fileFilter: (req, file, cb) => {
    if (file.mimetype === 'application/octet-stream' || 
        file.originalname.match(/\.(pcap|pcapng)$/i)) {
      cb(null, true);
    } else {
      cb(new Error('只支持 pcap 文件'));
    }
  }
});

// 解析结果存储
const results = new Map();

/**
 * 使用 tshark 解析 pcap 文件
 */
async function parsePcapFile(filePath) {
  return new Promise((resolve, reject) => {
    const result = {
      basicStats: {
        totalPackets: 0,
        totalRequests: 0,
        timeRange: { start: null, end: null }
      },
      httpRequests: [],
      methods: {},
      statusCodes: {},
      clientIPs: {},
      userAgents: {},
      paths: {},
      hourlyDistribution: Array.from({ length: 24 }, (_, i) => ({ hour: i, count: 0 }))
    };

    // 使用 tshark 解析 HTTP 流量
    const command = `tshark -r "${filePath}" -Y "http" -T fields -e frame.time -e ip.src -e ip.dst -e http.request.method -e http.host -e http.request.uri -e http.response.code -e http.user_agent -e http.request.version -e http.response.phrase`;

    exec(command, { maxBuffer: 1024 * 1024 * 10 }, (error, stdout, stderr) => {
      if (error && !stdout) {
        reject(new Error(`解析失败: ${stderr || error.message}`));
        return;
      }

      const lines = stdout.split('\n').filter(line => line.trim());
      result.basicStats.totalPackets = lines.length;

      lines.forEach(line => {
        const fields = line.split('\t');
        if (fields.length >= 6) {
          parseHttpPacket(fields, result);
        }
      });

      // 后处理：计算统计信息
      processStatistics(result);
      resolve(result);
    });
  });
}

/**
 * 解析单个 HTTP 数据包
 */
function parseHttpPacket(fields, result) {
  const [
    frameTime, srcIp, dstIp, method, host, uri, 
    statusCode, userAgent, httpVersion, responsePhrase
  ] = fields;

  // 过滤非 HTTP 请求/响应
  if (!method && !statusCode) return;

  const isRequest = !!method;
  const timestamp = new Date(frameTime);

  // 更新时间范围
  if (!result.basicStats.timeRange.start || timestamp < result.basicStats.timeRange.start) {
    result.basicStats.timeRange.start = timestamp;
  }
  if (!result.basicStats.timeRange.end || timestamp > result.basicStats.timeRange.end) {
    result.basicStats.timeRange.end = timestamp;
  }

  if (isRequest) {
    // HTTP 请求
    result.basicStats.totalRequests++;
    
    const request = {
      timestamp,
      srcIp,
      dstIp,
      method,
      host: host || 'Unknown',
      uri: uri || '/',
      userAgent: userAgent || 'Unknown',
      httpVersion: httpVersion || 'HTTP/1.1'
    };

    result.httpRequests.push(request);

    // 统计请求方法
    result.methods[method] = (result.methods[method] || 0) + 1;

    // 统计客户端IP
    result.clientIPs[srcIp] = (result.clientIPs[srcIp] || 0) + 1;

    // 统计用户代理
    const simplifiedUA = simplifyUserAgent(userAgent);
    result.userAgents[simplifiedUA] = (result.userAgents[simplifiedUA] || 0) + 1;

    // 统计请求路径
    const path = uri.split('?')[0]; // 移除查询参数
    result.paths[path] = result.paths[path] || { count: 0, methods: {} };
    result.paths[path].count++;
    result.paths[path].methods[method] = (result.paths[path].methods[method] || 0) + 1;

    // 小时分布
    const hour = timestamp.getHours();
    result.hourlyDistribution[hour].count++;

  } else {
    // HTTP 响应
    result.statusCodes[statusCode] = (result.statusCodes[statusCode] || 0) + 1;
  }
}

/**
 * 简化 User Agent
 */
function simplifyUserAgent(userAgent) {
  if (!userAgent) return 'Unknown';
  
  const ua = userAgent.toLowerCase();
  if (ua.includes('chrome') && !ua.includes('edg')) return 'Chrome';
  if (ua.includes('firefox')) return 'Firefox';
  if (ua.includes('safari') && !ua.includes('chrome')) return 'Safari';
  if (ua.includes('edg')) return 'Edge';
  if (ua.includes('bot') || ua.includes('crawler')) return 'Bot/Crawler';
  if (ua.includes('mobile')) return 'Mobile Browser';
  return 'Other';
}

/**
 * 后处理统计信息
 */
function processStatistics(result) {
  // 对路径按访问量排序
  result.topPaths = Object.entries(result.paths)
    .map(([path, data]) => ({
      path,
      count: data.count,
      methods: data.methods
    }))
    .sort((a, b) => b.count - a.count)
    .slice(0, 50);

  // 对IP按访问量排序
  result.topIPs = Object.entries(result.clientIPs)
    .map(([ip, count]) => ({ ip, count }))
    .sort((a, b) => b.count - a.count)
    .slice(0, 20);

  // 对UserAgent按访问量排序
  result.topUserAgents = Object.entries(result.userAgents)
    .map(([ua, count]) => ({ ua, count }))
    .sort((a, b) => b.count - a.count)
    .slice(0, 15);
}

// API 路由

/**
 * 上传并解析 pcap 文件
 */
app.post('/api/analyze', upload.single('pcapFile'), async (req, res) => {
  try {
    if (!req.file) {
      return res.status(400).json({ error: '请上传 pcap 文件' });
    }

    const fileId = path.basename(req.file.filename, path.extname(req.file.filename));
    
    console.log(`开始解析文件: ${req.file.originalname}`);
    
    const analysisResult = await parsePcapFile(req.file.path);
    
    // 存储结果
    results.set(fileId, {
      id: fileId,
      filename: req.file.originalname,
      uploadTime: new Date(),
      analysis: analysisResult
    });

    // 清理上传的文件
    await fs.unlink(req.file.path);

    res.json({
      success: true,
      fileId,
      message: `解析完成，共处理 ${analysisResult.basicStats.totalPackets} 个数据包`
    });

  } catch (error) {
    console.error('解析错误:', error);
    res.status(500).json({ 
      success: false, 
      error: error.message 
    });
  }
});

/**
 * 获取分析结果
 */
app.get('/api/results/:fileId', (req, res) => {
  const { fileId } = req.params;
  const result = results.get(fileId);

  if (!result) {
    return res.status(404).json({ error: '分析结果不存在' });
  }

  res.json(result);
});

/**
 * 获取所有分析结果列表
 */
app.get('/api/results', (req, res) => {
  const resultList = Array.from(results.values()).map(item => ({
    id: item.id,
    filename: item.filename,
    uploadTime: item.uploadTime,
    stats: {
      totalPackets: item.analysis.basicStats.totalPackets,
      totalRequests: item.analysis.basicStats.totalRequests
    }
  }));

  res.json(resultList);
});

/**
 * 删除分析结果
 */
app.delete('/api/results/:fileId', (req, res) => {
  const { fileId } = req.params;
  
  if (results.has(fileId)) {
    results.delete(fileId);
    res.json({ success: true, message: '删除成功' });
  } else {
    res.status(404).json({ error: '分析结果不存在' });
  }
});

// 启动服务
app.listen(PORT, () => {
  console.log(`PCAP 解析服务运行在 http://localhost:${PORT}`);
  console.log('确保系统已安装 tshark:');
  console.log('  Ubuntu/Debian: sudo apt-get install tshark');
  console.log('  CentOS/RHEL: sudo yum install wireshark');
});